package com.atguigu.java.ai.langchain4j.store;

import com.atguigu.java.ai.langchain4j.Bean.ChatMessages;
import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.data.message.ChatMessageDeserializer;
import dev.langchain4j.data.message.ChatMessageSerializer;
import dev.langchain4j.store.memory.chat.ChatMemoryStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Component;

import java.util.LinkedList;
import java.util.List;

@Component
 public class MongoChatMemoryStore implements ChatMemoryStore {
    @Autowired
    private MongoTemplate mongoTemplate;
    /**
     * 根据记忆ID获取聊天信息列表
     * 此方法解释了如何通过记忆ID查询数据库，以获取与该记忆相关的所有聊天信息
     * 它首先构建查询条件，然后使用MongoTemplate执行查询操作，最后将查询结果转换为聊天信息列表返回
     *
     * @param memoryId 记忆的唯一标识符，用于查询聊天信息
     * @return 包含聊天信息的列表如果找不到相关信息，则返回空列表
     */
    @Override
    public List<ChatMessage> getMessages(Object memoryId) {
        // 构建查询条件，指定记忆ID
        Criteria criteria = Criteria.where("memoryId").is(memoryId);
        // 创建查询对象，包含上述条件
        Query query = new Query(criteria);
        // 执行查询，尝试获取一个ChatMessages实例
        ChatMessages chatMessages = mongoTemplate.findOne(query, ChatMessages.class);
        // 如果没有找到相关记录，返回一个新的空链表
        if(chatMessages == null) return new LinkedList<>();
        // 使用ChatMessageDeserializer将查询结果中的内容转换为聊天信息列表并返回
        String content = chatMessages.getContent();
        return ChatMessageDeserializer.messagesFromJson(content);
    }
    /**
     * 更新或插入聊天消息
     *
     * 该方法用于更新数据库中的聊天消息如果指定的记忆体ID已存在，则更新其消息内容；
     * 如果不存在，则插入新的聊天消息记录此方法首先根据memoryId构建查询条件，
     * 然后将传入的消息列表序列化为JSON格式并设置为更新内容最后，使用upsert方法执行查询和更新/插入操作
     *
     * @param memoryId 记忆体ID，用于标识特定的聊天记录
     * @param messages 聊天消息列表，包含要更新的聊天信息
     */
    @Override
    public void updateMessages(Object memoryId, List<ChatMessage> messages) {
        // 构建查询条件，指定memoryId
        Criteria criteria = Criteria.where("memoryId").is(memoryId);
        Query query = new Query(criteria);
        Update update = new Update();

        // 将聊天消息列表序列化为JSON格式，并设置为更新内容
        update.set("content", ChatMessageSerializer.messagesToJson(messages));

        // 根据query条件能查询出文档，则修改文档；否则新增文档
        mongoTemplate.upsert(query, update, ChatMessages.class);
    }

    /**
     * 根据记忆ID删除聊天消息
     *
     * 此方法通过接收一个记忆ID来删除数据库中所有与该记忆ID相关的聊天消息
     * 它首先构建一个查询条件，然后使用该条件创建一个查询对象，最后执行删除操作
     *
     * @param memoryId 记忆的唯一标识符，用于定位并删除相关的聊天消息
     */
    @Override
    public void deleteMessages(Object memoryId) {
        // 构建查询条件，指定memoryId字段匹配传入的记忆ID
        Criteria criteria = Criteria.where("memoryId").is(memoryId);

        // 创建查询对象，包含上述查询条件
        Query query = new Query(criteria);

        // 执行删除操作，移除所有符合查询条件的ChatMessages文档
        mongoTemplate.remove(query, ChatMessages.class);
    }
}